package parser;

import lexer.Lexer;

/**
 * 语法解析器
 * Created by weijianyu on 2017/1/13.
 */
public class Parser {
    private Lexer lexer;

    String[] registers = {"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"};
    private int register = 0;

    private String newRegister() {
        if (register >= registers.length) {
            System.out.println("Expression too complex: " + lexer.yylineno);
            System.exit(1);
        }

        return registers[register++];
    }

    private void freeRegister(String reg) {
        if (register > 0) {
            registers[register--] = reg;
        } else {
            System.out.println("(Internal error) register stack underflow: " + lexer.yylineno);
        }
    }

    public Parser(Lexer lexer) {
        this.lexer = lexer;
    }

    public void statements() {
        // statements -> expression; | expression; statements
        String reg = newRegister();
        expression(reg);
        freeRegister(reg);
        if (lexer.match(Lexer.SEMI)) {
            lexer.advance();
        } else {
            System.out.println("Inserting missing semicolon: " + lexer.yylineno);
        }

        while (!lexer.match(Lexer.EOI)) {
            expression(reg);
            freeRegister(reg);
            if (lexer.match(Lexer.SEMI)) {
                lexer.advance();
            } else {
                System.out.println("Inserting missing semicolon: " + lexer.yylineno);
            }
        }
    }

    private void expression(String reg) {
        // expression -> term expression'
        // expression' -> PLUS term expression' | 空
        String reg2;
        term(reg);
        while (lexer.match(Lexer.PLUS)) {
            lexer.advance();
            reg2 = newRegister();
            term(reg2);
            System.out.println(reg + "+=" + reg2);
            freeRegister(reg2);
        }
        if (lexer.match(Lexer.UNKNOWN_SYMBOL)) {
            // 未知标签
            System.out.println("unknow symbol: " + lexer.yytext);
        } else {
            // 为空不处理
        }
    }

    private void term(String reg) {
        // term ->  factor term'
        // term' -> TIMES factor term' | '空'
        String reg2;
        factor(reg);
        while (lexer.match(Lexer.TIMES)) {
            lexer.advance();
            reg2 = newRegister();
            factor(reg2);
            System.out.println(reg + "*=" + reg2);
            freeRegister(reg2);
        }
        if (lexer.match(Lexer.UNKNOWN_SYMBOL)) {
            // 未知标签
            System.out.println("unknow symbol: " + lexer.yytext);
        } else {
            // 为空不处理
        }
    }

    private void factor(String reg) {
        // factor -> NUM_OR_ID | LP expression RP
        if (lexer.match(Lexer.NUM_OR_ID)) {
            System.out.println(reg + "=" + lexer.yytext);
            lexer.advance();
        } else if (lexer.match(Lexer.LP)) {
            lexer.advance();
            expression(reg);
            if (lexer.match(Lexer.RP)) {
                lexer.advance();
            } else {
                System.out.println("Missmatched parenthesis: " + lexer.yylineno);
            }
        } else {
            System.out.println("Number or identifier expected: " + lexer.yylineno);
        }
    }

    public static void main(String[] args) {
        Lexer lexer = new Lexer();
        Parser parser = new Parser(lexer);
        parser.statements();
    }
}